<?php
ArrowController::importModel("org.arrowplatform.orm.ArrowOrmConfig");
ArrowController::importModel("org.arrowplatform.orm.ArrowOrmException");
ArrowController::importModel("org.arrowplatform.orm.ArrowOrmCriteria");
ArrowController::importModel("org.arrowplatform.orm.db.ArrowOrmMysql");

/**
 * @author Pawel Giemza
 * @version 1.1
 * @package Arrow
 * @subpackage Orm
 * @link http://arrowplatform.org/
 * @copyright 2009 3code 
 * @license GNU LGPL
 * 
 * @date 2009-06-01 
*/

/** 
 * Interfaces ArrowOrmPersistent with specific DB handling classes
 *
 */
class ArrowOrmSqlRouter
{
	/**
	 * List of database connections
	 *
	 * @var Array
	 */
	private static $databases;

	/**
	 * List of accepted character sets
	 *
	 * @var Array
	 */
	private static $accepted_charset = array(
      'utf8'=>'utf8',
      'utf 8'=>'utf8',
      'utf-8'=>'utf8',
      'utf_8'=>'utf8',            
      'utf'=>'utf8',     
      'latin2'=>'latin2',
      'latin 2'=>'latin2',
      'latin-2'=>'latin2',
      'latin_2'=>'latin2',
      'latin1'=>'latin1',
      'latin 1'=>'latin1',
      'latin-1'=>'latin1',      
      'latin_1'=>'latin1'
	);
	private static $defaultDbName = null;
	/**
	 * Return database connection object to database specified in parameter. If not specified default (i.e. first defined in XML file) database will be accessed
	 *
	 * @param String $dbName
	 * @return Object
	 */	
	private static function getDB($dbName='_default_')
	{	
		//ArrowLogger::log("[ArrowOrmSqlRouter] getDB() 'db'=>$dbName", ArrowLogger::EL_INFO );
		if ($dbName == '_default_'){
			if (self::$defaultDbName === null)
				self::$defaultDbName = ArrowOrmConfig::getDefaultDbName();
			$dbName = self::$defaultDbName;
		}
		
		if (!isset( self::$databases[ $dbName ])){
			$dbId = $dbName;
			$dbConf = ArrowOrmConfig::getDBConf($dbId);
			$trans=false;
			
			$charset = 'utf8';
			if (isset($dbConf['charset']) && array_key_exists(trim($dbConf['charset']), self::$accepted_charset) )
        		$charset = self::$accepted_charset[ $dbConf['charset'] ];
				
			if ($dbConf['transactions']==="yes" || $dbConf['transactions']==="true" || $dbConf['transactions']===true || $dbConf['transactions']===1 )
				$trans = true;
			
			self::$databases[$dbName] = self::connect( 'ArrowOrm'.ucwords($dbConf['type']),$dbConf['host'],$dbConf['user'],$dbConf['password'],$dbConf['name'],$charset,$trans,$dbId);
		}		
		return self::$databases[$dbName];
	}
	
	/**
	 * Establish connection with DB
	 *
	 * Note: This function creates new DB object 
	 * 
	 * @param String $type - type of DB (mysql, postgres, ... )
	 * @param String $host - Address of DB host
	 * @param String $user - DB user
	 * @param String $password - DB password
	 * @param String $dbname - DB name
	 * @param String $charset - charset used by DB	 
	 * @param bool $transaction - Are transactions enabled
	 * @param String $alias - Name under which DB will be seen BY ORM classes
	 * @return Object
	 */
	public static function connect($type, $host, $user, $password, $dbname, $charset, $transaction, $alias){
		//ArrowLogger::log("[ArrowOrmSqlRouter] connect() ,'db'=>$dbname", ArrowLogger::EL_INFO );
		$db = new $type( $host,$user,$password,$dbname, $charset, $transaction, $alias);		
		return $db;
	}
	
	/**
	 * SQL select statement
	 *
	 * @param String $table - name of table
	 * @param String $dbname - DB alias
	 * @param Array $columnList - list of available columns (obtained from ArrowOrmConfig)
	 * @param Criteria $criteria
	 * @param Selector $selector
	 * @return Resource
	 */
	public static function select($table, $dbname, $criteria, $getQuery = false){
		//ArrowLogger::log("[ArrowOrmSqlRouter] select() 'db'=>$dbname", ArrowLogger::EL_INFO );
		$db = self::getDB($dbname);		
		$dat = $db->select($table, $criteria, $getQuery);			
		return $dat;
	}	
	
	/**
	 * SQL insert statement
	 *
	 * @param String $table - table name
	 * @param String $dbname - DB name
	 * @param Array $data - object data
	 * @return bool
	 */
	public static function insert($table, $dbname, $data){		
		//ArrowLogger::log("[ArrowOrmSqlRouter] insert() 'db'=>$dbname", ArrowLogger::EL_INFO );
		$db = self::getDB($dbname);		
		$dat = $db->insert($table, $data);			
		return $dat;	
	}	

	/**
	 * SQL update statement
	 *
	 * @param String $table - table name
	 * @param String $dbname - DB name
	 * @param Array $data - object data
	 * @param Criteria $criteria
	 * @return bool
	 */
	public static function update($table, $dbname, $data, $criteria){
		//ArrowLogger::log("[ArrowOrmSqlRouter] update() 'db'=>$dbname", ArrowLogger::EL_INFO );
		$db = self::getDB($dbname);		
		$dat = $db->update($table, $data, $criteria);			
		return $dat;				
	}	
	
	/**
	 * SQL delete statement
	 *
	 * @param String $table - table name
	 * @param String $dbname - DB name
	 * @param Criteria $criteria
	 * @return bool
	 */
	public static function delete($table, $dbname, $criteria){
		//ArrowLogger::log("[ArrowOrmSqlRouter] delete() 'db'=>$dbname", ArrowLogger::EL_INFO );
		$db = self::getDB($dbname);		
		$dat = $db->delete($table, $criteria);			
		return $dat;		
	}			

	/**
	 * SQL join statement
	 *
	 * @param String $dbname
	 * @param array of Criteria $criterias
	 * @return Resource
	 */
	public static function join($dbname, $criterias, $getQuery = false){
		//ArrowLogger::log("[ArrowOrmSqlRouter] join()','db'=>$dbname", ArrowLogger::EL_INFO );
		$db = self::getDB($dbname);	
		$dat = $db->join($criterias, $getQuery);
		return $dat;	
	}
	
	/**
	 * Convert result resource returned by DB into array of rows.
	 * Note: If DB is not specified default will be used. 
	 *
	 * @param Resource $result
	 * @param String $dbname
	 * @return Array
	 */
	public static function toArray( $result, $dbname = "_default_" ){
		//ArrowLogger::log("[ArrowOrmSqlRouter] toArray() 'db'=>$dbname", ArrowLogger::EL_INFO );		
		$db = self::getDB($dbname);			
		return $db->toArray( $result );
	}
	
	/**
	 * Preform custom query on specified DB.
	 * Note: If DB is not specified Default will be used.
	 *
	 * @param String $query
	 * @param String $dbname
	 * @return Resource
	 */
	public static function query( $query, $dbname = "_default_", $multiInsert=false ){
		//ArrowLogger::log("[ArrowOrmSqlRouter] query() 'db'=>$dbname, 'query'=>$query", ArrowLogger::EL_INFO );
		$db = self::getDB($dbname);	
		return $db->query( $query, $multiInsert);
	}
	
	public static function encodeCustomString($str, $dbname = "_default_") {
		$db = self::getDB($dbname);	
		return $db->encodeCustomString($str);
	}
	
	public static function conditionsToSql($criteria, $dbname = "_default_") {
		$db = self::getDB($dbname);
		return $db->conditionsToSql($criteria);
	}
}
?>